package com.tgpms.interfaces.dto;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.tgpms.common.Result;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.util.Map;

/**
 * @author eve
 * <p>
 * 相关接口的暴露
 */
public interface VformInterface {

    /**
     * 1. VForm 第一个接口： 登陆接口
     *
     * @param username   用户名
     * @param password   密码
     * @param tns        账号所在系统标识
     * @param systemCode 系统代码--标示调用接口系统
     * @return 返回值信息
     * <p>
     * success    登录成功
     * not_found_username	用户账号错误
     * not_correct	账号密码错误,
     * other_wrong	其它错误
     * ip_wrong	ip限制
     */
    Result login(String username, String password, String systemCode) throws UnsupportedEncodingException;

    /**
     * 2. VForm 第二个接口： 数据插入操作
     *
     * @param progCode 屏幕编码
     * @param data     数据，数据按照指定格式提交
     * @return 返回信息：
     * <p>
     * validateError	校验错误信息，插入成功字段为空
     * status	success:插入成功，
     * error:插入失败，错误信息见validateError
     */
    Result insert(String progCode, Object data);

    /**
     * 3. VForm 第三个接口： 数据批量插入操作
     *
     * @param progCode 屏幕编码 例：D3141C
     * @param data     数据，数据按照指定格式提交 例：
     *                 [{
     *                 "PO_NO" : "BB080101019",
     *                 "REF_CODE" : "ML2016111601",
     *                 "PO_ITEM" : "BG01010102",
     *                 "COMPANY" : "XJKLLG",
     *                 "PROJECT_COST_DATE" : "2016-12-15",
     *                 "CONTRACTOR_QTY" : "1",
     *                 "CONTRACTOR_FAMT" : "5880"
     *                 }, {
     *                 "PO_NO" : "BB080101019",
     *                 "REF_CODE" : "ML2016111601",
     *                 "PO_ITEM" : "BG01010103",
     *                 "COMPANY" : "XJKLLG",
     *                 "PROJECT_COST_DATE" : "2016-12-15",
     *                 "CONTRACTOR_QTY" : "1",
     *                 "CONTRACTOR_FAMT" : "5880"
     *                 }, {
     *                 "PO_NO" : "BB080101019",
     *                 "REF_CODE" : "ML2016111601",
     *                 "PO_ITEM" : "BG01010104",
     *                 "COMPANY" : "XJKLLG",
     *                 "PROJECT_COST_DATE" : "2016-12-15",
     *                 "CONTRACTOR_QTY" : "1",
     *                 "CONTRACTOR_FAMT" : "5880"
     *                 }
     *                 ]
     * @return 返回信息
     * <p>
     * validateError	校验错误信息，插入成功字段为空
     * status	success:插入成功，
     * error:插入失败，错误信息见validateError
     * <p>
     */
    Result insertBatch(String progCode, Object data);

    /**
     * 4. VForm 第四个接口： 数据修改操作
     *
     * @param progCode            屏幕编码 例：D3161C
     * @param key                 记录的关键字段，用来确定唯一记录 例：
     *                            {
     *                            "PO_NO":"BB080101019",
     *                            "INVOICE_NO":"TEST2016111602"
     *                            }
     * @param data                需要更新的字段数据 例：
     *                            {
     *                            "CONTRACTOR_APPROVAL_BY":"TGPMS",
     *                            "CONTRACTOR_APPROVAL_DATE":"2016/11/18"
     *                            }
     * @param dataownermode       dataowner模式（该参数的可选值为"Y"和"N"，Y表示采用新的dataonwer模式，适用于福能投、长江大保护的tgpms环境，N表示原来的dataowner模式，适用于其他tgpms环境）
     * @param needswitchdataowner 是否需要先切换用户的当前dataowner（该参数的可选值为"Y"和"N"，Y表示需要切换，N表示不用切换）
     * @param switchdataowner     需要切换的dataowner
     * @return 返回信息
     * <p>
     * validateError	校验错误信息，更新成功字段为空
     * status	success: 更新成功，
     * error: 更新失败，错误信息见validateError
     * <p>
     */
    Result update(String progCode, String key, String data, String dataownermode, String needswitchdataowner, String switchdataowner);

    /**
     * 5. VForm 第五个接口： 数据批量修改操作
     *
     * @param progCode            屏幕编码 例：D3161C
     * @param data                需要更新的字段数据 例：
     *                            [{
     *                            "KEY" : {
     *                            "PO_NO" : "BB080101019",
     *                            "INVOICE_NO" : "TEST2016112205"
     *                            },
     *                            "DATA" : {
     *                            "CONTRACTOR_INPUT_BY" : "TGPMS",
     *                            "CONTRACTOR_INPUT_DATE" : "2016/11/18",
     *                            "CONTRACTOR_STATUS" : "1"
     *                            }
     *                            },
     *                            {
     *                            "KEY" : {
     *                            "PO_NO" : "BB080101019",
     *                            "INVOICE_NO" : "TEST2016112205"
     *                            },
     *                            "DATA" : {
     *                            "CONTRACTOR_INPUT_BY" : "TGPMS",
     *                            "CONTRACTOR_INPUT_DATE" : "2016/11/18",
     *                            "CONTRACTOR_STATUS" : "1"
     *                            }
     *                            }
     *                            ]
     * @param dataownermode       dataowner模式（该参数的可选值为"Y"和"N"，Y表示采用新的dataonwer模式，适用于福能投、长江大保护的tgpms环境，N表示原来的dataowner模式，适用于其他tgpms环境）
     * @param needswitchdataowner 是否需要先切换用户的当前dataowner（该参数的可选值为"Y"和"N"，Y表示需要切换，N表示不用切换）
     * @param switchdataowner     需要切换的dataowner
     * @return 返回信息
     * <p>
     * validateError	校验错误信息，更新成功字段为空
     * status	success: 更新成功，
     * error: 更新失败，错误信息见validateError
     * <p>
     */
    Result updateBatch(String progCode, JSONArray data, String dataownermode, String needswitchdataowner, String switchdataowner);

    /**
     * 6. VForm 第六个接口： 数据删除操作
     *
     * @param progCode 屏幕编码 例：D3141C
     * @param key      记录的关键字段，用来确定唯一记录{
     *                 "PO_NO" : "BB080101019",
     *                 "REF_CODE" : "ML2016111601",
     *                 "PO_ITEM" : "BG01010102",
     *                 "COMPANY" : "XJKLLG",
     *                 "PROJECT_COST_DATE" : "2016-12-15"
     *                 }
     * @return 返回信息
     * <p>
     * validateError	校验错误信息，更新成功字段为空
     * status	success: 更新成功，
     * error: 更新失败，错误信息见validateError
     * <p>
     */
    Result delete(String progCode, String key);

    /**
     * 7. VForm 第七个接口： 数据批量删除操作
     *
     * @param progCode 屏幕编码
     * @param key      记录的关键字段，用来确定唯一记录
     *                 例：
     *                 [{
     *                 "PO_NO" : "BB080101019",
     *                 "REF_CODE" : "ML2016111601",
     *                 "PO_ITEM" : "BG01010102",
     *                 "COMPANY" : "XJKLLG",
     *                 "PROJECT_COST_DATE" : "2016-12-15"
     *                 }, {
     *                 "PO_NO" : "BB080101019",
     *                 "REF_CODE" : "ML2016111601",
     *                 "PO_ITEM" : "BG01010103",
     *                 "COMPANY" : "XJKLLG",
     *                 "PROJECT_COST_DATE" : "2016-12-15"
     *                 }, {
     *                 "PO_NO" : "BB080101019",
     *                 "REF_CODE" : "ML2016111601",
     *                 "PO_ITEM" : "BG01010104",
     *                 "COMPANY" : "XJKLLG",
     *                 "PROJECT_COST_DATE" : "2016-12-15"
     *                 }
     *                 ]
     * @return 返回信息
     * <p>
     * validateError	校验错误信息，更新成功字段为空
     * status	success: 更新成功，
     * error: 更新失败，错误信息见validateError
     */
    Result deleteBatch(String progCode, JSONArray key);

    /**
     * 8. VForm 第八个接口： 数据查询操作
     *
     * @param progCode            屏幕编码
     * @param data                查询条件，可为空
     *                            格式如下：
     *                            {"task_code":"208 -20808-  16","sub_task_code":"010102"}
     *                            注：在字段名后面加上符号=，例如{"task_code=":"208 -20808-  16","sub_task_code=":"010102"}
     *                            则表示该字段条件采用=进行查询，否则用like进行查询
     * @param page                页码
     * @param size                页规则
     * @param dataownermode       dataowner模式（该参数的可选值为"Y"和"N"，Y表示采用新的dataonwer模式，适用于福能投、长江大保护的tgpms环境，N表示原来的dataowner模式，适用于其他tgpms环境）
     * @param needswitchdataowner 是否需要先切换用户的当前dataowner（该参数的可选值为"Y"和"N"，Y表示需要切换，N表示不用切换）
     * @param switchdataowner     需要切换的dataowner
     * @return 返回信息
     * <p>
     * 返回值：json数据集合，如果没有查询到记录则为[];
     * <p>
     * 实际返回内容为“[{"DATA_OWNER":"BHTPMS","TASK_CODE":"208    -20808  -  16","INSERT_DATE":"2016-02-24","REAL_END_DATE":"","END_DATE":"2015-06-01","ADJUSTMENT_REASON":"","SUB_TASK_DESCRIPTION":"测试数据导航树01","RN":"1","MODIFY_DATE":"2016-03-11","ADJUSTMENT_REASON_CLASS":"","START_DATE":"2015-01-15","DOCUMENTS_NO":"3","IS_FLOOR":"N","LEVEL_NO":"1","TASK_NAME":"测试项目32432","ESTIMATED_SUBMIT_DATE":"","TASK_STAGE_DESCRIPTION":"任务执行","ESTIMATED_START_DATE":"","MONTH_FINISHED_PERCENT":"","REAL_START_DATE":"","INSERT_USER":"TGPMS","TASK_STAGE":"EX","SUB_TASK_CODE":"01","MODIFY_USER":"TGPMS"}]”
     */
    Result find(String progCode, String data, String page, String size, String dataownermode, String needswitchdataowner, String switchdataowner);

    /**
     * 9. VForm 第九个接口： 范围查询操作
     *
     * @param progCode            屏幕编码
     * @param data                查询条件，可为空
     *                            格式如下：
     *                            [{
     *                            "name" : "date_rcvd",
     *                            "range" : "Y",
     *                            "begin" : "2017/01/01",
     *                            "end" : "2017/04/25"
     *                            }, {
     *                            "name" : "invoice_no",
     *                            "range" : "Y",
     *                            "begin" : "1234567890",
     *                            "end" : "1234567899"
     *                            }
     *                            ]
     *                            说明：其中name为作为条件的字段名称
     *                            Range表示是否是范围查询：
     *                            Y：表示字段为范围查询，这时begin和end都不能为空
     *                            N:表示字段不是范围查询，begin不能为空，end可以为空
     * @param page                页码
     * @param size                页规则
     * @param dataownermode       dataowner模式（该参数的可选值为"Y"和"N"，Y表示采用新的dataonwer模式，适用于福能投、长江大保护的tgpms环境，N表示原来的dataowner模式，适用于其他tgpms环境）
     * @param needswitchdataowner 是否需要先切换用户的当前dataowner（该参数的可选值为"Y"和"N"，Y表示需要切换，N表示不用切换）
     * @param switchdataowner     需要切换的dataowner
     * @return 返回信息
     * <p>
     * 实际返回内容为{"message":"success","count":12,"status":"success","data":[{},{}]}
     * 返回结果说明：
     * message：查询结果说明
     * success 查询成功
     * param_error 表示参数错误
     * count: 查询结果条数
     * status:查询状态
     * success 查询成功
     * fail 查询错误
     * data:结果集合
     */
    Result queryRange(String progCode, Object data, String page, String size, String dataownermode, String needswitchdataowner, String switchdataowner);

    /**
     * 10. VForm 第十个接口： 数据记录数查询操作
     *
     * @param progCode            屏幕编码
     * @param data                查询条件，可为空
     *                            格式如下：
     *                            {"task_code":"208 -20808-  16","sub_task_code":"010102"}
     *                            注：在字段名后面加上符号=，例如{"task_code=":"208 -20808-  16","sub_task_code=":"010102"}
     *                            则表示该字段条件采用=进行查询，否则用like进行查询
     * @param dataownermode       dataowner模式（该参数的可选值为"Y"和"N"，Y表示采用新的dataonwer模式，适用于福能投、长江大保护的tgpms环境，N表示原来的dataowner模式，适用于其他tgpms环境）
     * @param needswitchdataowner 是否需要先切换用户的当前dataowner（该参数的可选值为"Y"和"N"，Y表示需要切换，N表示不用切换）
     * @param switchdataowner     需要切换的dataowner
     * @return 返回信息
     * <p>
     * 返回值：
     * 错误：
     * {
     * "status" : "fail",
     * "message" : "user_access_error"
     * "data" : ""
     * }
     * <p>
     * 正确：
     * {
     * "status" : "success",
     * "data" : "5"
     * }
     * 其中data，表示返回的记录条数。
     */
    Result queryTotal(String progCode, String data, String dataownermode, String needswitchdataowner, String switchdataowner);

    /**
     * 11. VForm 第十一个接口： 范围记录数查询操作
     *
     * @param progCode            屏幕编码
     * @param data                查询条件，可为空
     *                            格式如下：
     *                            [{
     *                            "name" : "date_rcvd",
     *                            "range" : "Y",
     *                            "begin" : "2017/01/01",
     *                            "end" : "2017/04/25"
     *                            }, {
     *                            "name" : "invoice_no",
     *                            "range" : "Y",
     *                            "begin" : "1234567890",
     *                            "end" : "1234567899"
     *                            }
     *                            ]
     *                            说明：其中name为作为条件的字段名称
     *                            Range表示是否是范围查询：
     *                            Y：表示字段为范围查询，这时begin和end都不能为空
     *                            N:表示字段不是范围查询，begin不能为空，end可以为空
     * @param dataownermode       dataowner模式（该参数的可选值为"Y"和"N"，Y表示采用新的dataonwer模式，适用于福能投、长江大保护的tgpms环境，N表示原来的dataowner模式，适用于其他tgpms环境）
     * @param needswitchdataowner 是否需要先切换用户的当前dataowner（该参数的可选值为"Y"和"N"，Y表示需要切换，N表示不用切换）
     * @param switchdataowner     需要切换的dataowner
     * @return 返回信息
     * <p>
     * 返回值：
     * 错误：
     * {
     * "status" : "fail",
     * "message" : "user_access_error"
     * "data" : ""
     * }
     * <p>
     * 正确：
     * {
     * "status" : "success",
     * "data" : "5"
     * }
     */
    Result queryRangeTotal(String progCode, Object data, String dataownermode, String needswitchdataowner, String switchdataowner);
    /**
     * 12.1 VForm 第十二个接口： 特殊查询接口（固定多表联合查询） 操作
     *
     * @param code                固定编码：固定编码，调用方提供脚本后，我们给出约定的编码，脚本中需要通过传参替换的地方用[SQL1]、[SQL2]……依次代替
     * @param param               查询条件，可为空
     *                            格式如下：
     *                            {"[SQL1]":"AND inv.po_no='lwtest' AND inv.invoice_no='lwtest'","[SQL2]":"AND inv.status='1'"}
     *                            注：参数键值对的KEY包括三部分，用|分隔，第一部分是表名.字段名，第二部分是匹配符（如like、=、>、<等），第三部分是类型，默认可不填，若是日期型则填date。
     * @param page                页码
     * @param size                页规则
     * @param dataownermode       dataowner模式（该参数的可选值为"Y"和"N"，Y表示采用新的dataonwer模式，适用于福能投、长江大保护的tgpms环境，N表示原来的dataowner模式，适用于其他tgpms环境）
     * @param needswitchdataowner 是否需要先切换用户的当前dataowner（该参数的可选值为"Y"和"N"，Y表示需要切换，N表示不用切换）
     * @param switchdataowner     需要切换的dataowner
     * @return 返回值
     * <p>
     * 返回值：json格式，包括total和rows。total是总条数，rows是数据集合。
     */
    Result multiForMsQueryBySql(String code, String param, String page, String size, String dataownermode, String needswitchdataowner, String switchdataowner);
    
    /**
     * 13. VForm 第十三个接口： 值列表分页查询接口 操作
     *
     * @param item_name     值列表字段
     * @param data          举例：{"LABEL":"PO_DESC,PO_NO,PROJECT,PO_STATUS","progCode":"D3161OF","PO_STATUS":"3"}
     *                      LABEL表示需要查询的字段，progCode表示当前屏幕，后面附上值列表查询需要的参数和值
     * @param page          页码
     * @param size          页规格
     * @param param         筛选条件，用like匹配。例如：{"ENTITIES.FULL_NAME":"陈"}
     * @param dataownermode 是否启用调用方的dataowner进行查询（该参数的可选值为"Y"和"N"，Y表示用调用方的dataowner进行查询（同时切换当前用户的datawoner），N表示不用切换，用当前的dataowner进行查询）
     * @param dataowner     需要切换并带上条件的dataowner值
     * @return 返回值
     * <p>
     * 返回值：json格式，包括lovstring、total、start、end、label、rows。total是总条数，rows是数据集合，lovstring是查询脚本，start是开始条数，end是结束条数，label是查询显示的字段。
     */
    Result getLovPage(String item_name, String data, String page, String size, String param, String dataownermode, String dataowner);

    /**
     * 14. VForm 第十四个接口： 值列表查询接口 操作
     *
     * @param item_name     值列表字段
     * @param data          举例：{"LABEL":"PO_DESC,PO_NO,PROJECT,PO_STATUS","progCode":"D3161OF","PO_STATUS":"3"}
     *                      LABEL表示需要查询的字段，progCode表示当前屏幕，后面附上值列表查询需要的参数和值
     * @param param         筛选条件，用like匹配。例如：{"ENTITIES.FULL_NAME":"陈"}
     * @param dataownermode 是否启用调用方的dataowner进行查询（该参数的可选值为"Y"和"N"，Y表示用调用方的dataowner进行查询（同时切换当前用户的datawoner），N表示不用切换，用当前的dataowner进行查询）
     * @param dataowner     需要切换并带上条件的dataowner值
     * @return 返回值
     * <p>
     * 返回值：json格式，包括lovstring、total、start、end、label、rows。total是总条数，rows是数据集合，lovstring是查询脚本，start是开始条数，end是结束条数，label是查询显示的字段。
     */
    Result getLov(String item_name, String data, String param, String dataownermode, String dataowner) throws UnsupportedEncodingException;

    /**
     * 解析 MyDesk传递过来的Token
     *
     * @param token     token
     * @param sessionid Jsessionid的值
     * @param systemid  第三方应用在MyDesk中登记的系统别名
     * @param logoutUrl 第三方应用用户登出的方法
     * @return 返回值
     * <p>
     * sc_user, sc_psw, user_id，full_name等	用户绑定的第三方应用账号、密码、用户在MyDesk中的用户信息
     * not_login	验证失败，没有获取到用户信息，此时，需要重新跳转到获取token的地址：http://ip:port/UserAuthenCenter/sso/login?url=xxx/login
     */
    Result parsingMyDeskToken(String token, String sessionid, String systemid, String logoutUrl);

    /**
     * mydesk的解密
     * @param password
     * @return
     */
    String descrypt(String password)throws Exception;

    /**
     * @Author guan
     * @Description vform 报表打印接口
     * @Date 14:31 2019-11-7
     * @Param param 报表打印参数
     * @Param reportCode 报表编码
     * @Param desformat 报表打印格式
     * @return com.tgpms.common.Result
     **/
    Result runReport(String param, String reportCode, String desformat) throws Exception;

    /**
     * vform 旧报表打印接口
     * @param param
     * @param reportCode
     * @return
     */
    Result runReportForOld(String param, String reportCode) throws Exception;

    /**
     * 通过手机号获取账号和密码
     * @param phone
     * @param pp
     * @return Result
     */
    Result getUserTgpmsBymobile(String phone, String pp);
}
